<script setup>
import { defineComponent, onMounted,ref, onBeforeUnmount} from 'vue'
// import { EffectComposer, RenderPass } from 'three/examples/jsm/postprocessing';
import {EffectComposer, RenderPass} from 'postprocessing'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import {
  Scene,PerspectiveCamera,WebGLRenderer,WebGLRenderTarget, PCFSoftShadowMap,
  HalfFloatType, Vector3,PointLight, Mesh,Color,MeshBasicMaterial,
  BoxGeometry,PointLightHelper, PlaneGeometry,DoubleSide, MeshStandardMaterial,
  DirectionalLight, DirectionalLightHelper
} from 'three';
import { GodraysPass } from 'three-good-godrays';


// const { scene, camera, renderer } = initYourScene();

const threeBg = ref()

let scene, camera, renderer, composer, renderPass, control

function init() {
  scene = new Scene();
  camera = new PerspectiveCamera(45,threeBg.value.clientWidth/threeBg.value.clientHeight)
  camera.position.y=12;
  camera.position.z=20;
  camera.lookAt(new Vector3(0,0,0));
  renderer = new WebGLRenderer({antialias:true, alpha: false});

  threeBg.value.appendChild(renderer.domElement)
  renderer.setSize(threeBg.value.clientWidth,threeBg.value.clientHeight)
  // shadowmaps are needed for this effect
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type =PCFSoftShadowMap;
  renderer.shadowMap.autoUpdate = true;

  const geometry = new BoxGeometry( 50, 1, 30 );
  const material = new MeshStandardMaterial({
    color: 0x222222, // 深色减少反光干扰
    roughness: 0.9,
    metalness: 0.1
  });
  const cube = new Mesh( geometry, material );
  cube.castShadow = true;
  cube.receiveShadow = true;
  cube.position.y = -10

  // 添加一个遮挡平面
  const planeGeometry = new PlaneGeometry(4, 4);
  const planeMaterial = new MeshStandardMaterial({ color: 0xff0000, side: DoubleSide }); // 红色便于调试
  const plane = new Mesh(planeGeometry, planeMaterial);
  plane.rotation.x = Math.PI / 2; // 让平面水平
  plane.position.y = 2; // 在光源下方2个单位（光源y=10）
  plane.castShadow = true; // 投射阴影
  plane.receiveShadow = true;
  const copyPlane = plane.clone();
  copyPlane.position.x = -5
  scene.add(plane);
  scene.add(copyPlane);
  scene.add( cube );

  // godrays can be cast from either `PointLight`s or `DirectionalLight`s
  const lightPos = new Vector3(-10, 10, 0);
  /*const pointLight = new PointLight(0xff0000, 10, 50);
  pointLight.castShadow = true;
  pointLight.shadow.mapSize.width = 1024;
  pointLight.shadow.mapSize.height = 1024;
  pointLight.shadow.autoUpdate = true;
  pointLight.shadow.camera.near = 0.1;
  pointLight.shadow.camera.far = 1000;
  pointLight.shadow.camera.updateProjectionMatrix();
  pointLight.position.copy(lightPos);
  const pointLightHelper = new PointLightHelper( pointLight, 4 );
  scene.add( pointLightHelper );
  scene.add(pointLight);*/

  const directionalLight = new DirectionalLight( 0xffffff, 1 );
  directionalLight.position.copy(lightPos);
  directionalLight.castShadow = true
  scene.add( directionalLight );
  const helper = new DirectionalLightHelper( directionalLight, 5 );
  scene.add( helper );
  /*const renderTarget = new WebGLRenderTarget(
      threeBg.value.clientWidth,
      threeBg.value.clientHeight,
      { type: HalfFloatType, multisampling: 8 } // 正确传递配置
  );
  // set up rendering pipeline and add godrays pass at the end
  composer = new EffectComposer(renderer, renderTarget);*/
  composer = new EffectComposer(renderer, {
    frameBufferType: HalfFloatType, // 通过配置对象指定类型
    multisampling: 4 // 可选：开启抗锯齿
  });

  renderPass = new RenderPass(scene, camera);
  renderPass.renderToScreen = false;
  composer.addPass(renderPass);

  control = new OrbitControls(camera, threeBg.value)
  // Default values are shown.  You can supply a sparse object or `undefined`.
  const params = {
    density: 1 / 128,
    maxDensity: 0.5,
    edgeStrength: 2,
    edgeRadius: 2,
    distanceAttenuation: 2,
    color: new Color(0xffffff),
    raymarchSteps: 60,
    blur: true,
    gammaCorrection: true,
  };

  const godraysPass = new GodraysPass(directionalLight, camera, params);
// If this is the last pass in your pipeline, set `renderToScreen` to `true`
  godraysPass.renderToScreen = true;
  composer.addPass(godraysPass);
}

onMounted(() => {
  init()
  function animate() {
    requestAnimationFrame(animate);
    composer.render();
  }
  requestAnimationFrame(animate);
})

</script>

<template>
<div class="god-light" ref="threeBg">

</div>
</template>

<style scoped lang="stylus">
.god-light
  width 100%
  height 100%
  position absolute
  top 0
  left 0
  z-index 1
</style>